import pandas as pd
from lifelines import CoxTimeVaryingFitter
import datetime
import matplotlib.pyplot as plt
import seaborn as sns;sns.set()
import geopandas as gpd
import shapely.wkt
import os
import folium
from shapely import wkt
import branca.colormap as cm
from branca.element import Template, MacroElement
from matplotlib.patches import Rectangle
from matplotlib.dates import date2num
from folium import plugins
import jinja2
from shapely.ops import cascaded_union
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
from sklearn import preprocessing
import numpy as np
Our monitoring project keeps daily track of the main adopted restrictions in order to monitor and evaluate the national responses, both in terms of which policies have been adopted as well as their timing in each country and have a clear view on the global state of the fight against Corona Virus. For this purpose, we built a dataset for monitoring policies that Governments have taken as countermeasures to tackle the spread of COVID-19. At the moment we are monitoring over 41 countries over different policies, from Lockdown, to closure of schools and cancellation of large events (for a detailed list of all variables we monitor see the information page of the dataset. We cross those data together with epidemic data from the Johns Hopkins Coronavirus Resource Center (JHCRC), as well with economic, political and demographic features of the countries under analysis.Our research objective is to understand why some governments are acting with delays, and what are the effects of this policies on the epidemic curve.
At the moment we cover 38 countries, the selection has been made based on most developed countries and most hit as of the end of March 2020. This list of countries include all 35 OECD countries. In the map the yellow-coloured countries are those under analysis, in addition the violet-coloured countries are those for which we have data on virus spread from the JHCRC.
Below we give a map visualization of the dataset, for further informations please see the home page of the website for related documents and papers..
folder="D:\\database_vari_miei\\covid_database\\"
DATASET=pd.read_excel("POLITICAL_COVID_29_03_2020.xlsx",sheet_name="DATA")
### select only useful
DATASET=DATASET.iloc[0:DATASET["ISO3"].last_valid_index()+1,:]
DATASET_COMPLETE=pd.read_csv(folder+os.listdir(folder)[-1],index_col=0,low_memory=False)
# ## list of country for which we have political data
country_analized=DATASET['ISO3'].unique()
policy_var=DATASET.columns
fig,axs=plt.subplots(figsize=(15,10))
mappa_mondo=gpd.read_file("C:\\Users\\gabri\\Desktop\\COVID\\limiti_mondo")
GPD_PLOT=gpd.GeoDataFrame(DATASET_COMPLETE.groupby('ISO3',as_index=False)['geometry'].first())
GPD_PLOT['geometry']=GPD_PLOT['geometry'].apply(lambda x:shapely.wkt.loads(x))
GPD_PLOT.set_geometry('geometry',inplace=True)
GPD_PLOT=GPD_PLOT.loc[GPD_PLOT['ISO3'].isin(DATASET['ISO3'].unique()),:]
##sfondo
mappa_mondo.plot(color='lightgrey',ax=axs)
GPD_PLOT.plot(ax=axs,color="limegreen",legend=True)
axs.set_title('Dataset coverage update at '+datetime.datetime.today().strftime("%d/%m/%Y"));
axs.set_axis_off()
The graph below, along time, how countries are adopting measures in response to a spike in the number of registered cases. As we can see, the week between the 16th and the 23rd of March has been of fundamental importance, with more than 20 countries deciding to close their schools, and 15 countries adopting "lockdown" policies. This graph suggests countries are choosing coordinately on their policies by looking at "what the others do". A visual interpretation of the graph suggests countries are following the spread of the virus when choosing their timing of adoption, instead of anticipating it. While the other MAPS below show countries’ adoption over different policies (school closing, lockdown, digital tracking and suspension of elections).
# selezionare solo i paesi censiti
fig,axs=plt.subplots(figsize=(14,8))
DF=DATASET_COMPLETE.loc[DATASET_COMPLETE['ISO3'].isin(country_analized),:].copy()
policies=["LOCKDOWN_dummy","LOCKDOWN_LOCAL_dummy","SCHOOL_CLOSING_dummy","EVENT_LARGE_dummy"]
polic=["lockdown",'local lockdown','school closure','closure of large events']
diz_rename={}
for x,y in zip(policies,polic):
diz_rename[x]="n. of countries adopting "+y
numero_policy_adopter=DF.groupby(['time'],as_index=False)["LOCKDOWN_dummy","LOCKDOWN_LOCAL_dummy","SCHOOL_CLOSING_dummy","EVENT_LARGE_dummy"].sum()
numero_casi=DF.groupby(['time'],as_index=False)['confirmed_cases'].sum()
DF_PLOT=pd.merge(numero_policy_adopter,numero_casi,on='time')
# nuovo_nome="Number of countries that have closed Schools (right axis)"
DF_PLOT.rename(diz_rename,axis=1,inplace=True)
DF_PLOT.set_index(pd.to_datetime(DF_PLOT['time']),inplace=True)
DF_PLOT.sort_index(inplace=True)
DF_PLOT.loc[:,diz_rename.values()].plot(ax=axs);
plt.legend(loc='upper left',fontsize=13);
axs2 = axs.twinx()
DF_PLOT.loc[:,['confirmed_cases']].plot(ax=axs2,linestyle="dashed",color='black',linewidth=3)
plt.legend(loc='upper center',fontsize=13,labels=["total confirmed COVID-19 cases (right axis)"]);
plt.tight_layout()
The next maps shows for some selected policies of our dataset, which countries are adopter. By dragging the mouse on a certain countries you can see also how many confirmed and deaths cases the country has.
def plot_policy_country(var):
variable=var+"_dummy"
fig,ax =plt.subplots(figsize=(20,8))
DATASET_COMPLETE.loc[DATASET_COMPLETE[variable]==1,['ISO3',variable,var]].drop_duplicates().sort_values(var)
countries_lockdown=DATASET_COMPLETE.groupby('time',as_index=False)[variable].sum()
countries_lockdown['time']=pd.to_datetime(countries_lockdown['time'])
countries_lockdown.set_index('time',inplace=True)
countries_lockdown.sort_index(inplace=True)
countries_lockdown.plot(ax=ax,legend=False)
data_inizio_grafico=countries_lockdown.index.min()
## add image
lista_date=[]
lista_paesi=[]
db_codici=DATASET_COMPLETE.loc[DATASET_COMPLETE[variable]==1,['ISO2',variable,var]].drop_duplicates().sort_values(var)
for data in db_codici[var].unique():
lista_fips=list(db_codici.loc[db_codici[var]==data,'ISO2'])
lista_date.append(data)
lista_paesi.append(lista_fips)
for data,lista_paese in zip(lista_date,lista_paesi):
### correzione per date fuori dal grafico
if pd.to_datetime(data)<data_inizio_grafico:
data_posizione=(data_inizio_grafico-data_inizio_grafico).days
else:
data_posizione=(pd.to_datetime(data)-data_inizio_grafico).days
i=0
for country in lista_paese:
a_partire_da=countries_lockdown.iloc[data_posizione].iloc[0]
nome_stringa="C:\\Users\\gabri\\Desktop\\COVID\\png100px\\"+country.lower()+".png"
im = plt.imread(nome_stringa)
oi = OffsetImage(im,zoom=0.2)
posizione_data=data_posizione
pos_asse_x=ax.get_xlim()[0]+data_posizione
pos_asse_y=a_partire_da+i
position_of_the_image=(pos_asse_x,pos_asse_y)
box = AnnotationBbox(oi, position_of_the_image, frameon=False)
ax.add_artist(box)
i+=1
ax.set_title(var)
#plt.text(10,10,"ciao")
#plt.tight_layout()
var_policy=DATASET_COMPLETE.columns[DATASET_COMPLETE.columns.str.contains("_dummy")]
lista_var=['ISO3']
lista_var.extend(var_policy)
## only one day
world=gpd.GeoDataFrame(DATASET_COMPLETE.loc[DATASET_COMPLETE['time']==DATASET_COMPLETE['time'].max(),:])
## aggiustare coordinaate settings
world.crs='EPSG:4326'
world['geometry'] = world['geometry'].apply(wkt.loads)
world.set_geometry('geometry',inplace=True)
### bisogna prima trasformarlo in json
worldjson=world.to_json()
def map_plotter(nome_variabile,colore_si='green',colore_no='violet'):
m = folium.Map(location=[41.8, +12.5], zoom_start=2, tiles="cartodbpositron")
var_dummy=nome_variabile+"_dummy"
style= lambda x :{'color': 'black','weight':0.5,'fillOpacity':0.2,'fillColor':colore_si if \
x['properties'][var_dummy]==0 \
else colore_no if x['properties'][var_dummy]==1 else 'grey'}
testo=folium.features.GeoJsonTooltip(fields=["Country/Region",nome_variabile,"confirmed_cases","deaths_cases"],aliases=["Country",nome_variabile,"confirmed_cases","deaths_cases"])
folium.GeoJson(worldjson, name=nome_variabile,style_function=style,tooltip=testo).add_to(m)
#m.get_root().html.add_child(folium.Element(legend_html))
m.get_root().add_child(macro)
return m
template = """
{% macro html(this, kwargs) %}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Draggable - Default functionality</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
$( function() {
$( "#maplegend" ).draggable({
start: function (event, ui) {
$(this).css({
right: "auto",
top: "auto",
bottom: "auto"
});
}
});
});
</script>
</head>
<body>
<div id='maplegend' class='maplegend'
style='position: absolute; z-index:9999; border:2px solid grey; background-color:rgba(255, 255, 255, 0.8);
border-radius:6px; padding: 10px; font-size:14px; right: 20px; top: 20px;'>
<div class='legend-title'>Legend</div>
<div class='legend-scale'>
<ul class='legend-labels'>
<li><span style='background:green;opacity:0.2;'></span>Not Adopted</li>
<li><span style='background:red;opacity:0.2;'></span>Lockdown</li>
<li><span style='background:grey;opacity:0.2;'></span>Not Available</li>
</ul>
</div>
</div>
</body>
</html>
<style type='text/css'>
.maplegend .legend-title {
text-align: left;
margin-bottom: 5px;
font-weight: bold;
font-size: 90%;
}
.maplegend .legend-scale ul {
margin: 0;
margin-bottom: 5px;
padding: 0;
float: left;
list-style: none;
}
.maplegend .legend-scale ul li {
font-size: 80%;
list-style: none;
margin-left: 0;
line-height: 18px;
margin-bottom: 2px;
}
.maplegend ul.legend-labels li span {
display: block;
float: left;
height: 16px;
width: 30px;
margin-right: 5px;
margin-left: 0;
border: 1px solid #999;
}
.maplegend .legend-source {
font-size: 80%;
color: #777;
clear: both;
}
.maplegend a {
color: #777;
}
</style>
{% endmacro %}"""
macro = MacroElement()
macro._template = Template(template)
map_plotter("LOCKDOWN",colore_no='red')
plot_policy_country(var="LOCKDOWN")
template = """
{% macro html(this, kwargs) %}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Draggable - Default functionality</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
$( function() {
$( "#maplegend" ).draggable({
start: function (event, ui) {
$(this).css({
right: "auto",
top: "auto",
bottom: "auto"
});
}
});
});
</script>
</head>
<body>
<div id='maplegend' class='maplegend'
style='position: absolute; z-index:9999; border:2px solid grey; background-color:rgba(255, 255, 255, 0.8);
border-radius:6px; padding: 10px; font-size:14px; right: 20px; top: 20px;'>
<div class='legend-title'>Legend</div>
<div class='legend-scale'>
<ul class='legend-labels'>
<li><span style='background:green;opacity:0.2;'></span>Schools open</li>
<li><span style='background:violet;opacity:0.2;'></span>Schools closed</li>
<li><span style='background:grey;opacity:0.2;'></span>Not Available</li>
</ul>
</div>
</div>
</body>
</html>
<style type='text/css'>
.maplegend .legend-title {
text-align: left;
margin-bottom: 5px;
font-weight: bold;
font-size: 90%;
}
.maplegend .legend-scale ul {
margin: 0;
margin-bottom: 5px;
padding: 0;
float: left;
list-style: none;
}
.maplegend .legend-scale ul li {
font-size: 80%;
list-style: none;
margin-left: 0;
line-height: 18px;
margin-bottom: 2px;
}
.maplegend ul.legend-labels li span {
display: block;
float: left;
height: 16px;
width: 30px;
margin-right: 5px;
margin-left: 0;
border: 1px solid #999;
}
.maplegend .legend-source {
font-size: 80%;
color: #777;
clear: both;
}
.maplegend a {
color: #777;
}
</style>
{% endmacro %}"""
macro = MacroElement()
macro._template = Template(template)
map_plotter("SCHOOL_CLOSING")
plot_policy_country(var="LOCKDOWN")
template = """
{% macro html(this, kwargs) %}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Draggable - Default functionality</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
$( function() {
$( "#maplegend" ).draggable({
start: function (event, ui) {
$(this).css({
right: "auto",
top: "auto",
bottom: "auto"
});
}
});
});
</script>
</head>
<body>
<div id='maplegend' class='maplegend'
style='position: absolute; z-index:9999; border:2px solid grey; background-color:rgba(255, 255, 255, 0.8);
border-radius:6px; padding: 10px; font-size:14px; right: 20px; top: 20px;'>
<div class='legend-title'>Legend</div>
<div class='legend-scale'>
<ul class='legend-labels'>
<li><span style='background:yellow;opacity:0.2;'></span>digital tracking</li>
<li><span style='background:green;opacity:0.2;'></span>NO Digital Tracking</li>
<li><span style='background:grey;opacity:0.2;'></span>Not Available</li>
</ul>
</div>
</div>
</body>
</html>
<style type='text/css'>
.maplegend .legend-title {
text-align: left;
margin-bottom: 5px;
font-weight: bold;
font-size: 90%;
}
.maplegend .legend-scale ul {
margin: 0;
margin-bottom: 5px;
padding: 0;
float: left;
list-style: none;
}
.maplegend .legend-scale ul li {
font-size: 80%;
list-style: none;
margin-left: 0;
line-height: 18px;
margin-bottom: 2px;
}
.maplegend ul.legend-labels li span {
display: block;
float: left;
height: 16px;
width: 30px;
margin-right: 5px;
margin-left: 0;
border: 1px solid #999;
}
.maplegend .legend-source {
font-size: 80%;
color: #777;
clear: both;
}
.maplegend a {
color: #777;
}
</style>
{% endmacro %}"""
macro = MacroElement()
macro._template = Template(template)
map_plotter("TRACKING",colore_no='yellow')
template = """
{% macro html(this, kwargs) %}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Draggable - Default functionality</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
$( function() {
$( "#maplegend" ).draggable({
start: function (event, ui) {
$(this).css({
right: "auto",
top: "auto",
bottom: "auto"
});
}
});
});
</script>
</head>
<body>
<div id='maplegend' class='maplegend'
style='position: absolute; z-index:9999; border:2px solid grey; background-color:rgba(255, 255, 255, 0.8);
border-radius:6px; padding: 10px; font-size:14px; right: 20px; top: 20px;'>
<div class='legend-title'>Legend</div>
<div class='legend-scale'>
<ul class='legend-labels'>
<li><span style='background:brown;opacity:0.2;'></span>business closure</li>
<li><span style='background:green;opacity:0.2;'></span>no closure</li>
<li><span style='background:grey;opacity:0.2;'></span>Not Available</li>
</ul>
</div>
</div>
</body>
</html>
<style type='text/css'>
.maplegend .legend-title {
text-align: left;
margin-bottom: 5px;
font-weight: bold;
font-size: 90%;
}
.maplegend .legend-scale ul {
margin: 0;
margin-bottom: 5px;
padding: 0;
float: left;
list-style: none;
}
.maplegend .legend-scale ul li {
font-size: 80%;
list-style: none;
margin-left: 0;
line-height: 18px;
margin-bottom: 2px;
}
.maplegend ul.legend-labels li span {
display: block;
float: left;
height: 16px;
width: 30px;
margin-right: 5px;
margin-left: 0;
border: 1px solid #999;
}
.maplegend .legend-source {
font-size: 80%;
color: #777;
clear: both;
}
.maplegend a {
color: #777;
}
</style>
{% endmacro %}"""
macro = MacroElement()
macro._template = Template(template)
map_plotter("CLOSING",colore_no="brown")
plot_policy_country(var="CLOSING")
template = """
{% macro html(this, kwargs) %}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Draggable - Default functionality</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
$( function() {
$( "#maplegend" ).draggable({
start: function (event, ui) {
$(this).css({
right: "auto",
top: "auto",
bottom: "auto"
});
}
});
});
</script>
</head>
<body>
<div id='maplegend' class='maplegend'
style='position: absolute; z-index:9999; border:2px solid grey; background-color:rgba(255, 255, 255, 0.8);
border-radius:6px; padding: 10px; font-size:14px; right: 20px; top: 20px;'>
<div class='legend-title'>Legend</div>
<div class='legend-scale'>
<ul class='legend-labels'>
<li><span style='background:steelblue;opacity:0.2;'></span>suspended elections</li>
<li><span style='background:green;opacity:0.2;'></span>not suspended</li>
<li><span style='background:grey;opacity:0.2;'></span>Not Available</li>
</ul>
</div>
</div>
</body>
</html>
<style type='text/css'>
.maplegend .legend-title {
text-align: left;
margin-bottom: 5px;
font-weight: bold;
font-size: 90%;
}
.maplegend .legend-scale ul {
margin: 0;
margin-bottom: 5px;
padding: 0;
float: left;
list-style: none;
}
.maplegend .legend-scale ul li {
font-size: 80%;
list-style: none;
margin-left: 0;
line-height: 18px;
margin-bottom: 2px;
}
.maplegend ul.legend-labels li span {
display: block;
float: left;
height: 16px;
width: 30px;
margin-right: 5px;
margin-left: 0;
border: 1px solid #999;
}
.maplegend .legend-source {
font-size: 80%;
color: #777;
clear: both;
}
.maplegend a {
color: #777;
}
</style>
{% endmacro %}"""
macro = MacroElement()
macro._template = Template(template)
map_plotter("ELECTIONS_SUSPENSION",colore_no="steelblue")
plot_policy_country(var="ELECTIONS_SUSPENSION")
by clicking on the link below you can see the raw code used to produce the graphs
from IPython.display import HTML
HTML('''<script>
code_show=true;
function code_toggle() {
if (code_show){
$('div.input').hide();
} else {
$('div.input').show();
}
code_show = !code_show
}
$( document ).ready(code_toggle);
</script>
<form action="javascript:code_toggle()"><input type="submit" value="Click here to toggle on/off the raw code."></form>''')